#include "protect.h"
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include "systemdata.h"
#include "drv_timer.h"
#include "delay.h"
#include "debug_uart.h"
#include "main.h"
#include "bat_afe.h"

static ProtectTimeout_t timeout;
static Timer_t *protect_timer = NULL;
static SysRunData_t *runinfo = NULL;
static SysConfData_t *confinfo = NULL;

typedef struct {
	uint16_t scdLockTimes;
	uint16_t dsgLockTimes;
	uint16_t chgLockTimes;
	struct{
		bool scdRecoverFlag;		//短路恢复标志
		bool chgOVerCurFlag;		//充电过流恢复标志
		bool dsgOverCurFlag;		//放电过流恢复标志		
	}bits;
}XgLockTimesData;

static XgLockTimesData lockTimesData;


static inline void batVolHighProtect(uint16_t delta_ms){	
		///////////////////////////各电芯电压高故障状态判断///////////////////////////
	for(uint8_t i=0;i<32;i++){
		if(i<confinfo->fctData.batNum){
			//判断某一串是否故障
			if(((runinfo->volProtByte.cellHgVolProt>>i)&0x01) == 0){
				if(runinfo->batVol[i] >= confinfo->errorData.batVolHigh.value){
					timeout.batVolHighTimer[i] += delta_ms;
					if(timeout.batVolHighTimer[i] >= ((uint32_t)confinfo->errorData.batVolHighTime)*1000){//达到单体过压判定时间
						timeout.batVolHighTimer[i] = 0;
						runinfo->volProtByte.cellHgVolProt |= (1<<i);	
						runinfo->fullChgFlag = true;//满充标志置位，用于在安时积分时将SOC置100				
					}
				}else{
					timeout.batVolHighTimer[i] = 0;
					runinfo->volProtByte.cellHgVolProt &= (~(1<<i));
				}
			}else{
				timeout.batVolHighTimer[i] = 0;
				if(runinfo->batVol[i] < confinfo->errorData.batVolHighRecover.value){//条件1：达到恢复值恢复
					runinfo->volProtByte.cellHgVolProt &= (~(1<<i));
				}
			}
		}else{
			runinfo->volProtByte.cellHgVolProt &= (~(1<<i));
		}
	}
	if(runinfo->volProtByte.cellHgVolProt){//条件2：放电电流大于1A恢复
		for(uint8_t i=0;i<confinfo->fctData.batNum;i++){
			timeout.batVolHighTimer[i] =0;
		}
		if(runinfo->batCur<0 && abs(runinfo->batCur) > 1000){
			runinfo->volProtByte.cellHgVolProt = 0;
		}
	}

	//------------------二级过压----------------------------------------//
	if(runinfo->volProtByte.volProt.bit.afeVolHgProt){
		runinfo->fullChgFlag = true;//满充标志置位，用于在安时积分时将SOC置100
		if(runinfo->batMaxVol < confinfo->errorData.batVolHighRecover.value||
			(runinfo->batCur<0 && abs(runinfo->batCur) > 1000)){//条件1：单体最高电压低于过充恢复值
			runinfo->volProtByte.volProt.bit.afeVolHgProt = 0;//单体过压故障位复位
			Afe_Clear_OV();
		}
	}
}

static inline void batVolLowProtect(uint16_t delta_ms){
	///////////////////////////各电芯电压低故障状态判断///////////////////////////
	runinfo->volProtByte.cellLowVolProt &= (~(1<<confinfo->fctData.batNum));
	for(uint8_t i=0;i<32;i++){
		if(i<confinfo->fctData.batNum){
			//判断某一串是否故障
			if(((runinfo->volProtByte.cellLowVolProt>>i)&0x01)==0){
				if(runinfo->batVol[i] <= confinfo->errorData.batVolLow.value){
					timeout.batVolLowTimer[i] += delta_ms;
					if(timeout.batVolLowTimer[i]  >= ((uint32_t)confinfo->errorData.batVolLowTime)*1000){//达到单体欠压判定时间
						timeout.batVolLowTimer[i]  = 0;
						runinfo->volProtByte.cellLowVolProt |= (1<<i);
						runinfo->fullDsgFlag = true;//满放标志置位	
						runinfo->rmCapEmptyFlag = true;			
					}
				}else{
					timeout.batVolLowTimer[i]  = 0;
					runinfo->volProtByte.cellLowVolProt &= (~(1<<i)) ;
				}
			}else{
				timeout.batVolLowTimer[i]  = 0;
				if(runinfo->batVol[i] >= confinfo->errorData.batVolLowRecover.value){//条件1：达到恢复电压
					runinfo->volProtByte.cellLowVolProt &= (~(1<<i));
				}
			}
		}else{
			runinfo->volProtByte.cellLowVolProt &= (~(1<<i));
		}
	}
	
	if(runinfo->volProtByte.cellLowVolProt){//条件2：接入充电器恢复
		for(uint8_t i=0;i<confinfo->fctData.batNum;i++){
			timeout.batVolLowTimer[i] =0;
		}
		if(runinfo->batState == chgState){
			runinfo->volProtByte.cellLowVolProt = 0;
		}			
	}
	//------------------二级欠压----------------------------------------//
	if(runinfo->volProtByte.volProt.bit.afeVolLowProt){
			runinfo->fullDsgFlag = true;//满放标志置位	
			runinfo->rmCapEmptyFlag = true;
			if(runinfo->batMinVol > confinfo->errorData.batVolLowRecover.value||
				runinfo->batState == chgState){//条件1：达到恢复电压条件2：接入充电器恢复
				runinfo->volProtByte.volProt.bit.afeVolLowProt = 0;//单体欠压故障位复位
				Afe_Clear_UV();
		}		
	}
}

static inline void packVolHighProtect(uint16_t delta_ms){
	///////////////////////////总过压判断与恢复///////////////////////////
	if(runinfo->volProtByte.volProt.bit.packVolHgProt == 0){
		if(runinfo->packVol >= confinfo->errorData.packVolHigh.value){//达到总压欠压保护值，开始计时
			timeout.packVolHighTimer += delta_ms;
			if(timeout.packVolHighTimer >= ((uint32_t)confinfo->errorData.packVolHighTime)*1000){//达到单体欠压判定时间
				timeout.packVolHighTimer = 0;
				runinfo->volProtByte.volProt.bit.packVolHgProt = 1;//总压故障位置位
			}
		}else{
			timeout.packVolHighTimer = 0;
		}
	}else{//总压过压恢复条件
		timeout.packVolHighTimer = 0;
		if(runinfo->packVol < confinfo->errorData.packVolHighRecover.value){//条件1：总压低于恢复值，
			runinfo->volProtByte.volProt.bit.packVolHgProt = 0;//总压故障位复位
		}
	}
	if(runinfo->batCur<0 && abs(runinfo->batCur) > 1000){//条件2：放电电流大于1A
		timeout.packVolHighTimer = 0;
		runinfo->volProtByte.volProt.bit.packVolHgProt = 0;//总压故障位复位
	}
}

//压差保护判断与恢复
static inline void batVolDiffProtect(uint16_t delta_ms){
//	printf("cellVolDiffProt = %d\n",runinfo->volProtByte.volProt.bit.cellVolDiffProt);
	if(runinfo->volProtByte.volProt.bit.cellVolDiffProt == 0){
		if(runinfo->maxDiffVol >= confinfo->errorData.batVolDiff.value){
			timeout.volDiffTimer += delta_ms;
			if(timeout.volDiffTimer >= ((uint32_t)confinfo->errorData.batVolDiffTime)*1000){
				timeout.volDiffTimer = 0;
				runinfo->volProtByte.volProt.bit.cellVolDiffProt = 1;
			}
		}else{
			timeout.volDiffTimer = 0;
		}
	}else{
		timeout.volDiffTimer = 0;
		if(runinfo->maxDiffVol < confinfo->errorData.batVolDiffRecover.value){
			runinfo->volProtByte.volProt.bit.cellVolDiffProt = 0;
		}
	}
}

static inline void packVolLowProtect(uint16_t delta_ms){
	///////////////////////////总欠压判断与恢复///////////////////////////
	if(runinfo->volProtByte.volProt.bit.packVolLowProt == 0){
		if(runinfo->packVol <= confinfo->errorData.packVolLow.value){//达到总压欠压保护值，开始计时
			timeout.packVolLowTimer += delta_ms;
			if(timeout.packVolLowTimer >= ((uint32_t)confinfo->errorData.packVolLowTime)*1000){//达到总压欠压判定时间
				timeout.packVolLowTimer = 0;
				runinfo->volProtByte.volProt.bit.packVolLowProt = 1;//总压欠压故障位置位
			}
		}else{
			timeout.packVolLowTimer = 0;
		}
	}else{//总欠压的恢复条件
		timeout.packVolLowTimer = 0;
		if(runinfo->packVol > confinfo->errorData.packVolLowRecover.value||
			runinfo->batState == chgState){//条件1：总压高于恢复值，条件2：接入充电器
			runinfo->volProtByte.volProt.bit.packVolLowProt = 0;//总压欠故障位复位
		}
	}
	if(runinfo->batState == chgState){
		timeout.packVolLowTimer = 0;
		runinfo->volProtByte.volProt.bit.packVolLowProt = 0;
	}	
}



static inline void envTempLowProtect(uint16_t delta_ms){
	///////////////////////////环境低温判断与恢复///////////////////////////
	if(runinfo->tempProtByte.bit.envTempLowProt == 0){
		if(runinfo->envTemp <= confinfo->errorData.envTempLow){
			timeout.envTempLowTimer += delta_ms;
			if(timeout.envTempLowTimer >= ((uint32_t)confinfo->errorData.envTempLowTime)*1000){
				timeout.envTempLowTimer = 0;
				runinfo->tempProtByte.bit.envTempLowProt = 1;
			}
		}else{
			timeout.envTempLowTimer = 0;
		}
	}else{//充电低温恢复
		timeout.envTempLowTimer = 0;
		if(runinfo->envTemp > confinfo->errorData.envTempLowRecover){//电池环境最低温度高于恢复值
			runinfo->tempProtByte.bit.envTempLowProt = 0;
		}
	}
}

static inline void envTempHighProtect(uint16_t delta_ms){
	///////////////////////////环境过温判断与恢复///////////////////////////
	if(runinfo->tempProtByte.bit.envTempHgProt == 0){
		if(runinfo->envTemp >= confinfo->errorData.envTempHigh){//达到过温保护值，开始计时
			timeout.envTempHighTimer += delta_ms;
			if(timeout.envTempHighTimer > ((uint32_t)confinfo->errorData.envTempHighTime)*1000){
				timeout.envTempHighTimer = 0;
				runinfo->tempProtByte.bit.envTempHgProt = 1;
			}
		}else{
			timeout.envTempHighTimer = 0;
		}
	}else{
		timeout.envTempHighTimer = 0;
		if(runinfo->envTemp < confinfo->errorData.envTempHighRecover){
			runinfo->tempProtByte.bit.envTempHgProt = 0;
		}
	}
}



static inline void chgTempLowProtect(uint16_t delta_ms){
	///////////////////////////充电低温判断与恢复///////////////////////////
	int8_t batTemp = runinfo->tempOne<runinfo->tempTwo?runinfo->tempOne:runinfo->tempTwo;//取较小值
	if(runinfo->tempProtByte.bit.chgTempLowProt == 0){
		if(batTemp <= confinfo->errorData.chgTempLow){//达到充电低温保护值，开始计时
			timeout.chgTempLowTimer += delta_ms;
			if(timeout.chgTempLowTimer >= ((uint32_t)confinfo->errorData.chgTempLowTime)*1000){
				timeout.chgTempLowTimer = 0;
				runinfo->tempProtByte.bit.chgTempLowProt = 1;
			}
		}else{
			timeout.chgTempLowTimer = 0;
		}
	}else{//充电低温恢复
		timeout.chgTempLowTimer = 0;
		if(batTemp > confinfo->errorData.chgTempLowRecover){//电池最低温度高于恢复值
			runinfo->tempProtByte.bit.chgTempLowProt = 0;
		}
	}
}

static inline void chgTempHighProtect(uint16_t delta_ms){
	///////////////////////////充电过温判断与恢复///////////////////////////
	int8_t batTemp = runinfo->tempOne>runinfo->tempTwo?runinfo->tempOne:runinfo->tempTwo;//取较大值
	if(runinfo->tempProtByte.bit.chgTempHgProt == 0){
		if(batTemp >= confinfo->errorData.chgTempHigh){//达到充电过温保护值，开始计时
			timeout.chgTempHighTimer += delta_ms;
			if(timeout.chgTempHighTimer > ((uint32_t)confinfo->errorData.chgTempHighTime)*1000){
				timeout.chgTempHighTimer = 0;
				runinfo->tempProtByte.bit.chgTempHgProt = 1;
			}
		}else{
			timeout.chgTempHighTimer = 0;
		}
	}else{
		timeout.chgTempHighTimer = 0;
		if(batTemp < confinfo->errorData.chgTempHighRecover){
			runinfo->tempProtByte.bit.chgTempHgProt = 0;
		}
	}
}

static inline void dsgTempLowProtect(uint16_t delta_ms){
	///////////////////////////放电低温判断与恢复///////////////////////////
	int8_t batTemp = runinfo->tempOne<runinfo->tempTwo?runinfo->tempOne:runinfo->tempTwo;//取较小值
	if(runinfo->tempProtByte.bit.disTempLowProt == 0){
		if(batTemp <= confinfo->errorData.dsgTempLow){//达到放电低温保护值，开始计时
			timeout.dsgTempLowTimer += delta_ms;
			if(timeout.dsgTempLowTimer >= ((uint32_t)confinfo->errorData.dsgTempLowTime)*1000){
				timeout.dsgTempLowTimer = 0;
				runinfo->tempProtByte.bit.disTempLowProt = 1;
			}
		}else{
			timeout.dsgTempLowTimer = 0;
		}
	}else{//放电低温恢复
		timeout.dsgTempLowTimer = 0;
		if(batTemp > confinfo->errorData.dsgTempLowRecover){//电池最低温度高于恢复值
			runinfo->tempProtByte.bit.disTempLowProt = 0;
		}
	}
}

static inline void dsgTempHighProtect(uint16_t delta_ms){
	///////////////////////////放电过温判断与恢复///////////////////////////
	int8_t batTemp = runinfo->tempOne>runinfo->tempTwo?runinfo->tempOne:runinfo->tempTwo;//取较大值
	if(runinfo->tempProtByte.bit.disTempHgProt == 0){
		if(batTemp >= confinfo->errorData.dsgTempHigh){//达到放电过温保护值，开始计时
			timeout.dsgTempHighTimer += delta_ms;
			if(timeout.dsgTempHighTimer > ((uint32_t)confinfo->errorData.dsgTempHighTime)*1000){
				timeout.dsgTempHighTimer = 0;
				runinfo->tempProtByte.bit.disTempHgProt = 1;
			}
		}else{
			timeout.dsgTempHighTimer = 0;
		}
	}else{
		timeout.dsgTempHighTimer = 0;
		if(batTemp < confinfo->errorData.dsgTempHighRecover){
			runinfo->tempProtByte.bit.disTempHgProt = 0;
		}
	}
}



//温差保护判断与恢复
static inline void tempDiffProtect(uint16_t delta_ms){
	uint8_t temp = abs(runinfo->tempOne - runinfo->tempTwo);
	if(runinfo->tempProtByte.bit.tempDiffProt == 0){
		if(temp >= confinfo->errorData.batTempDiff){
			timeout.tempDiffTimer += delta_ms;
			if(timeout.tempDiffTimer >= ((uint32_t)confinfo->errorData.batTempDiffTime)*1000){
				timeout.tempDiffTimer = 0;
				runinfo->tempProtByte.bit.tempDiffProt = 1;
			}
		}else{
			timeout.tempDiffTimer = 0;
		}
	}else{
		timeout.tempDiffTimer = 0;
		if(temp < confinfo->errorData.batTempDiffRecover){
			runinfo->tempProtByte.bit.tempDiffProt = 0;
		}
	}
}

static inline void mosTempHighProtect(uint16_t delta_ms){
	///////////////////////////MOS过温判断与恢复///////////////////////////
	signed char mosTemp = runinfo->mosTemp;
	if(runinfo->tempProtByte.bit.mosTempHgProt == 0){
		if(mosTemp >= confinfo->errorData.mosTempHigh){//达到MOS过温保护值，开始计时
			timeout.mosTempHighTimer += delta_ms;
			if(timeout.mosTempHighTimer > ((uint32_t)confinfo->errorData.mosTempHighTime)*1000){
				timeout.mosTempHighTimer = 0;
				runinfo->tempProtByte.bit.mosTempHgProt = 1;
			}
		}else{
			timeout.mosTempHighTimer = 0;
		}
	}else{
		timeout.mosTempHighTimer = 0;
		if(mosTemp < confinfo->errorData.mosTempHighRecover){
			runinfo->tempProtByte.bit.mosTempHgProt = 0;
		}
	}
}

///////////////////////////充电过流判断与恢复///////////////////////////
static inline void chgOverCurProtect(uint16_t delta_ms){
	
			////////////////三级充电过流
	if(runinfo->curProtByte.bit.chgCur3Prot==1){
		if((confinfo->errorData.chgOverCurLockTimes.value==0)||(lockTimesData.chgLockTimes < confinfo->errorData.chgOverCurLockTimes.value)){//放电过流没有锁定可以自动解除和充电解除，否则只能充电解除
			timeout.chgOverCur3RcvTimer += delta_ms;
			if(timeout.chgOverCur3RcvTimer >= ((uint32_t)confinfo->errorData.chgOverCur3RecoverTime.value)*1000||
				(runinfo->batCur<0 &&abs(runinfo->batCur) > 1000)){
				timeout.chgOverCur3RcvTimer = 0;
				runinfo->curProtByte.bit.chgCur3Prot = 0;
				Afe_Clear_OCC2();
			}
		}else{		
			if(runinfo->batCur<0 &&abs(runinfo->batCur) > 1000){
				lockTimesData.chgLockTimes = 0;
				runinfo->curProtByte.bit.chgCur3Prot = 0;
				Afe_Clear_OCC2();
			}
		}
	}
	////////////////二级充电过流
	if(runinfo->curProtByte.bit.chgCur2Prot==1){
		if((confinfo->errorData.chgOverCurLockTimes.value==0)||(lockTimesData.dsgLockTimes < confinfo->errorData.chgOverCurLockTimes.value)){//放电过流没有锁定可以自动解除和放电解除解除，否则只能放电解除
			timeout.chgOverCur2RcvTimer += delta_ms;
			if(timeout.chgOverCur2RcvTimer >= ((uint32_t)confinfo->errorData.chgOverCur2RecoverTime.value)*1000||
				(runinfo->batCur<0 &&abs(runinfo->batCur) > 1000)){
				timeout.chgOverCur2RcvTimer = 0;
				runinfo->curProtByte.bit.chgCur2Prot = 0;
				Afe_Clear_OCC1();
			}
		}else{		
			if(runinfo->batCur<0 &&abs(runinfo->batCur) > 1000){
				lockTimesData.chgLockTimes = 0;
				runinfo->curProtByte.bit.chgCur2Prot = 0;
				Afe_Clear_OCC1();
			}
		}
	}
	
	////////////////一级充电过流
	if(runinfo->curProtByte.bit.chgCUr1Prot == 0){
		unsigned int protectCurrent = 0;
		protectCurrent = confinfo->errorData.chgOverCurrent.value;
		protectCurrent *= 1000;//转换为mA
		if(runinfo->batCur >0 && abs(runinfo->batCur - 0) > protectCurrent){//达到充电过流保护值，开始计时
			timeout.chgOverCurTimer += delta_ms;
			if(timeout.chgOverCurTimer >= ((uint32_t)confinfo->errorData.chgOverCurrentTime)*1000){
				timeout.chgOverCurTimer = 0;
				runinfo->curProtByte.bit.chgCUr1Prot = 1;
			}
		}else{
			timeout.chgOverCurTimer = 0;
		}
	}else{//恢复条件
		if((confinfo->errorData.chgOverCurLockTimes.value==0)||(lockTimesData.chgLockTimes < confinfo->errorData.chgOverCurLockTimes.value)){//若果没有被锁定,可以自动恢复和放电恢复
			timeout.chgOverCurRcvTimer += delta_ms;//恢复计时
			if(timeout.chgOverCurRcvTimer >= ((uint32_t)confinfo->errorData.chgOverCurRecoverTime.value)*1000||
				(runinfo->batCur<0 &&abs(runinfo->batCur) > 1000)){//1、计时恢复，2、放电恢复
				timeout.chgOverCurRcvTimer = 0;
				runinfo->curProtByte.bit.chgCUr1Prot = 0;
			}		
		}else{//被锁定只能放电恢复，解除锁定
			if(runinfo->batCur<0 &&abs(runinfo->batCur) > 1000){
				runinfo->curProtByte.bit.chgCUr1Prot = 0;
				lockTimesData.chgLockTimes = 0;
			}		
		}
	}
	

	
	//充电过流锁定判断
	if(!runinfo->curProtByte.bit.chgCUr1Prot && !runinfo->curProtByte.bit.chgCur2Prot && !runinfo->curProtByte.bit.chgCur3Prot){
		lockTimesData.bits.chgOVerCurFlag = 0;
	}
	if(confinfo->errorData.chgOverCurLockTimes.value>0){
		if(!lockTimesData.bits.chgOVerCurFlag){
			if(runinfo->curProtByte.bit.chgCUr1Prot || runinfo->curProtByte.bit.chgCur2Prot ||runinfo->curProtByte.bit.chgCur3Prot){
				lockTimesData.bits.chgOVerCurFlag = 1;
				lockTimesData.chgLockTimes ++;
				if(lockTimesData.chgLockTimes == confinfo->errorData.chgOverCurLockTimes.value){
					printf("chg overcur err lock\n");
				}
			}
		}
	}	
}




static inline void dsgOverCurProtect(uint16_t delta_ms){	
	///////////////////////////四级放电过流恢复（硬件过流）///////////////////////////
	if(runinfo->curProtByte.bit.disCur4Prot==1){
		if((confinfo->errorData.disOverCurLockTimes.value==0)||(lockTimesData.dsgLockTimes < confinfo->errorData.disOverCurLockTimes.value)){//放电过流没有锁定可以自动解除和充电解除，否则只能充电解除
			timeout.dsgOverCur4RcvTimer += delta_ms;
			if(timeout.dsgOverCur4RcvTimer >= ((uint32_t)confinfo->errorData.dsgOverCur4RecoverTime.value)*1000||
				runinfo->batCur > 1000){
				timeout.dsgOverCur4RcvTimer = 0;
				runinfo->curProtByte.bit.disCur4Prot = 0;
				Afe_Clear_OCD2();
			}
		}else{		
			if(runinfo->batCur > 1000){
				lockTimesData.dsgLockTimes = 0;
				runinfo->curProtByte.bit.disCur4Prot = 0;
				Afe_Clear_OCD2();
			}
		}
	}
	
	///////////////////////////三级放电过流判断与恢复///////////////////////////
	if(runinfo->curProtByte.bit.disCur3Prot==1){
		if((confinfo->errorData.disOverCurLockTimes.value==0)||(lockTimesData.dsgLockTimes < confinfo->errorData.disOverCurLockTimes.value)){//放电过流没有锁定可以自动解除和充电解除，否则只能充电解除
			timeout.dsgOverCur3RcvTimer += delta_ms;
			if(timeout.dsgOverCur3RcvTimer >= ((uint32_t)confinfo->errorData.dsgOverCur3RecoverTime.value)*1000||
				runinfo->batCur > 1000){
				timeout.dsgOverCur3RcvTimer = 0;
				runinfo->curProtByte.bit.disCur3Prot = 0;
				Afe_Clear_OCD1();
			}
		}else{		
			if(runinfo->batCur > 1000){
				lockTimesData.dsgLockTimes = 0;
				runinfo->curProtByte.bit.disCur3Prot = 0;
				Afe_Clear_OCD1();
			}
		}
	}
	///////////////////////////二级放电过流判断与恢复///////////////////////////
	if(runinfo->curProtByte.bit.disCur2Prot == 0){
		uint32_t protectCurrent = confinfo->errorData.dsgOverCurrent2.value*1000;//转换为mA
		if(runinfo->batCur < 0 && abs(runinfo->batCur - 0) > protectCurrent){//放电情况下
			timeout.dsgOverCur2Timer += delta_ms;
			if(timeout.dsgOverCur2Timer >= ((uint32_t)confinfo->errorData.dsgOverCurrent2Time)*1000){
				timeout.dsgOverCur2Timer = 0;
				runinfo->curProtByte.bit.disCur2Prot = 1;
			}
		}else{//非放电状态或电流小于阈值
			timeout.dsgOverCur2Timer = 0;
		}
	}else{
		if((confinfo->errorData.disOverCurLockTimes.value==0)||(lockTimesData.dsgLockTimes < confinfo->errorData.disOverCurLockTimes.value)){
			timeout.dsgOverCur2RcvTimer += delta_ms;
			if(timeout.dsgOverCur2RcvTimer >= ((uint32_t)confinfo->errorData.dsgOverCur2RecoverTime.value)*1000||runinfo->batCur > 1000){
				timeout.dsgOverCur2RcvTimer = 0;
				runinfo->curProtByte.bit.disCur2Prot = 0;
			}		
		}else{
			if(runinfo->batCur > 1000){
				lockTimesData.dsgLockTimes = 0;
				runinfo->curProtByte.bit.disCur2Prot = 0;
			}
		}
	}
	///////////////////////////放电过流判断与恢复///////////////////////////
	if(runinfo->curProtByte.bit.disCur1Prot == 0){
		uint32_t protectCurrent = confinfo->errorData.dsgOverCurrent.value*1000;//转换为mA
		if(runinfo->batCur < 0 && abs(runinfo->batCur - 0) > protectCurrent){//放电情况下
			timeout.dsgOverCurTimer += delta_ms;
			if(timeout.dsgOverCurTimer >= ((uint32_t)confinfo->errorData.dsgOverCurrentTime)*1000){
				timeout.dsgOverCurTimer = 0;
				runinfo->curProtByte.bit.disCur1Prot = 1;
			}
		}else{//非放电状态或电流小于阈值
			timeout.dsgOverCurTimer = 0;
		}
	}else{
		if((confinfo->errorData.disOverCurLockTimes.value==0)||(lockTimesData.dsgLockTimes < confinfo->errorData.disOverCurLockTimes.value)){
			timeout.dsgOverCurRcvTimer += delta_ms;
			if(timeout.dsgOverCurRcvTimer >= ((uint32_t)confinfo->errorData.dsgOverCurRecoverTime.value)*1000||runinfo->batCur > 1000){
				timeout.dsgOverCurRcvTimer = 0;
				runinfo->curProtByte.bit.disCur1Prot = 0;
			}
		}else{
			if(runinfo->batCur > 1000){
				lockTimesData.dsgLockTimes = 0;
				runinfo->curProtByte.bit.disCur1Prot = 0;
			}
		}
		
	}
	
	//放电过流锁定判断
	if(!runinfo->curProtByte.bit.disCur1Prot && !runinfo->curProtByte.bit.disCur2Prot && !runinfo->curProtByte.bit.disCur3Prot &&!runinfo->curProtByte.bit.disCur4Prot){
		lockTimesData.bits.dsgOverCurFlag = 0;
	}
	if(lockTimesData.dsgLockTimes < confinfo->errorData.disOverCurLockTimes.value){
		if(!lockTimesData.bits.dsgOverCurFlag){
			if(runinfo->curProtByte.bit.disCur1Prot||runinfo->curProtByte.bit.disCur2Prot||runinfo->curProtByte.bit.disCur3Prot||runinfo->curProtByte.bit.disCur4Prot){
				lockTimesData.bits.dsgOverCurFlag = 1;
				lockTimesData.dsgLockTimes ++;
				if(lockTimesData.dsgLockTimes == confinfo->errorData.disOverCurLockTimes.value){
					printf("dsg overcur err is locked\n");
				}
			}
		}
	}
	
}


static inline void scdRecovery(uint16_t delta_ms){
	if(runinfo->curProtByte.bit.shortCurProt == 1){
		//没有锁定可以自动恢复
		if((confinfo->errorData.scdLockTimes.value == 0)||(lockTimesData.scdLockTimes < confinfo->errorData.scdLockTimes.value)){
			
			timeout.dsgOverCurRcvTimer += delta_ms;
			if(timeout.dsgOverCurRcvTimer >= ((uint32_t)confinfo->errorData.scdRecoverTime.value)*1000||runinfo->balState == chgState){
				timeout.dsgOverCurRcvTimer = 0;
				runinfo->curProtByte.bit.shortCurProt = 0;
				Afe_Clear_SCD();
			}
		}else{
			if(runinfo->batState == chgState){//短路锁定故障只能充电恢复
				lockTimesData.scdLockTimes = 0;
				runinfo->curProtByte.bit.shortCurProt = 0;
				Afe_Clear_SCD();
			}
		}
	}
	
	
	//锁定次数判断
	if(!runinfo->curProtByte.bit.shortCurProt){//没有短路故障
		lockTimesData.bits.scdRecoverFlag = 0;
	}
	if(lockTimesData.scdLockTimes < confinfo->errorData.scdLockTimes.value){//开启锁定次数
		if(!lockTimesData.bits.scdRecoverFlag){//
			if(runinfo->curProtByte.bit.shortCurProt){
				lockTimesData.bits.scdRecoverFlag = 1;
				lockTimesData.scdLockTimes ++;
			}		
		}
	}
}

//Alart故障的恢复,使用短路恢复的时间
static inline void afeComErrRecovery(uint16_t delta_ms){
	if(runinfo->afeProtByte.bit.comFaultProt == 1){
		timeout.afeComErrRcvTimer += delta_ms;
		if(timeout.afeComErrRcvTimer >= ((uint32_t)confinfo->errorData.scdRecoverTime.value)*1000){
			timeout.afeComErrRcvTimer = 0;
			runinfo->afeProtByte.bit.comFaultProt = 0;
		}
	}
}

//故障的恢复,使用短路恢复的时间
static inline void afeintErrRecovery(uint16_t delta_ms){
	if(runinfo->afeProtByte.bit.IntFaultProt == 1){
		timeout.afeIntErrRcvTime += delta_ms;
		if(timeout.afeIntErrRcvTime >= ((uint32_t)confinfo->errorData.scdRecoverTime.value)*1000){
			timeout.afeIntErrRcvTime = 0;
			runinfo->afeProtByte.bit.IntFaultProt  = 0;
			
		}
	}
}


static void protect_callback(void *data){
	uint16_t delta_ms = *(uint16_t *)data;
	batVolHighProtect(delta_ms);
	batVolLowProtect(delta_ms);
	packVolHighProtect(delta_ms);
	packVolLowProtect(delta_ms);
	chgTempLowProtect(delta_ms);
	chgTempHighProtect(delta_ms);
	dsgTempLowProtect(delta_ms);
	dsgTempHighProtect(delta_ms);
	mosTempHighProtect(delta_ms);
	chgOverCurProtect(delta_ms);
	dsgOverCurProtect(delta_ms);
	scdRecovery(delta_ms);
	afeComErrRecovery(delta_ms);
	afeintErrRecovery(delta_ms);
	envTempLowProtect(delta_ms);
	envTempHighProtect(delta_ms);
	batVolDiffProtect(delta_ms);
	tempDiffProtect(delta_ms);
}

void protectdialog_init(void){
	memset(&timeout,0,sizeof(ProtectTimeout_t));
	runinfo = getSysRunData();
	confinfo = getSysConfData();
	
	protect_timer = timer_create(protect_callback,100);
	while(protect_timer == NULL){
		printf("protect_timer create failed!\n");
		Delay_ms(1000);
	}
	timer_start(protect_timer);
}
